Tiling a rectangle with the fewest squares¶
Time: O(N2xM2xM^(NxM)); Space: O(NxM); hard
Given a rectangle of size n x m, find the minimum number of integer-sided squares that tile the rectangle.
Example 1:
Input: n = 2, m = 3
Output: 3
Explanation:
3 squares are necessary to cover the rectangle.
2 (squares of 1x1)
1 (square of 2x2)
Example 2:
Input: n = 5, m = 8
Output: 5
Example 3:
Input: n = 11, m = 13
Output: 6
Constraints:
1 <= n <= 13
1 <= m <= 13
Hints:
Can you use backtracking to solve this problem ?.
Suppose you’ve placed a bunch of squares. Where is the natural spot to place the next square ?.
The maximum number of squares to be placed will be ≤ max(n,m).
[1]:
class Solution1(object):
"""
Time: O(N^2*M^2*M^(N*M)), given M < N
Space: O(N*M)
"""
def tilingRectangle(self, n, m):
"""
:type n: int
:type m: int
:rtype: int
"""
def find_next(board):
for i in range(len(board)):
for j in range(len(board[0])):
if not board[i][j]:
return i, j
return -1, -1
def find_max_length(board, i, j):
max_length = 1
while i+max_length-1 < len(board) and \
j+max_length-1 < len(board[0]):
for r in range(i, i+max_length-1):
if board[r][j+max_length-1]:
return max_length-1
for c in range(j, j+max_length):
if board[i+max_length-1][c]:
return max_length-1
max_length += 1
return max_length-1
def fill(board, i, j, length, val):
for r in range(i, i+length):
for c in range(j, j+length):
board[r][c] = val
def backtracking(board, count, result):
if count >= result[0]: # pruning
return
i, j = find_next(board)
if (i, j) == (-1, -1): # finished
result[0] = min(result[0], count)
return
max_length = find_max_length(board, i, j)
for k in reversed(range(1, max_length+1)):
fill(board, i, j, k, 1)
backtracking(board, count+1, result)
fill(board, i, j, k, 0)
if m > n:
return self.tilingRectangle(m, n)
board = [[0]*m for _ in range(n)]
result = [float("inf")]
backtracking(board, 0, result)
return result[0]
[2]:
s = Solution1()
n = 2
m = 3
assert s.tilingRectangle(n, m) == 3
n = 5
m = 8
assert s.tilingRectangle(n, m) == 5
n = 11
m = 13
assert s.tilingRectangle(n, m) == 6